package ca.paulshin.yunatube.main;

import java.lang.reflect.Constructor;
import java.util.Locale;

import android.app.AlertDialog;
import android.app.NotificationManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Point;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.text.InputFilter;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.view.Display;
import android.widget.EditText;
import ca.paulshin.yunatube.GCMActivity;
import ca.paulshin.yunatube.R;
import ca.paulshin.yunatube.YunaTubeApplication;
import ca.paulshin.yunatube.YunaTubeBaseFragment;
import ca.paulshin.yunatube.common.Constants;
import ca.paulshin.yunatube.common.Preference;
import ca.paulshin.yunatube.common.Utils;
import ca.paulshin.yunatube.database.YuNaTubeSqliteDatabase;
import ca.paulshin.yunatube.image.album.PhotoListFragment;
import ca.paulshin.yunatube.services.DownloadService;
import ca.paulshin.yunatube.services.GCMIntentService;
import ca.paulshin.yunatube.widget.slidingmenu.SlidingMenu;

import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;

public class MainActivity extends GCMActivity {

	private YunaTubeBaseFragment mContent;
	protected Fragment mFrag;

	private SlidingMenu menu;

	private Handler mHandler;
	private boolean closeAppMsgFlag;
	private boolean notification;

	private static final String IS_RATE_DONE = "is_rate_done";
	private static final String VISIT_NUMBER = "visit_number";
	public static final String IS_LOCALE_CHANGED = "is_locale_changed";
	public static final String NICKNAME = "nickname";
	
	public static final String EXTRA_FRAGMENT = "extra_fragment";

	@SuppressWarnings("deprecation")
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setTitle(R.string.app_name);
		setContentView(R.layout.responsive_content_frame);

		// Check if the user enabled push notification
		if (!Preference.contains(Constants.NOTIFICATION)) {
			Preference.put(Constants.NOTIFICATION, true);
			notification = true;
		} else {
			notification = Preference.getBoolean(Constants.NOTIFICATION);
		}

		// Track visit number
		Preference.put(VISIT_NUMBER, Preference.contains(VISIT_NUMBER) ? Preference.getInt(VISIT_NUMBER) + 1 : 1);
		
		// Set user nickname
		if (!YunaTubeApplication.debuggable) {
			if (!Preference.contains(NICKNAME))
				showNicknameDialog();
			else
				showRateDialog();
		}

		// Check if the content frame contains the menu frame
		menu = getSlidingMenu();
		
		setBehindContentView(R.layout.menu_frame);
		if (savedInstanceState == null) {
			FragmentTransaction t = getSupportFragmentManager().beginTransaction();
			mFrag = new MainMenuFragment();
			t.replace(R.id.menu_frame, mFrag);
			t.addToBackStack(mFrag.getClass().getSimpleName());
			t.commit();
		} else {
			mFrag = (Fragment)getSupportFragmentManager().findFragmentById(R.id.menu_frame);
		}
		
		// Set Main Content
		Bundle bundle = getIntent().getExtras();
		if (bundle != null && bundle.containsKey(EXTRA_FRAGMENT)) {
			try {
				@SuppressWarnings("unchecked")
				Class<? extends YunaTubeBaseFragment> clazz = (Class<? extends YunaTubeBaseFragment>) bundle.getSerializable(EXTRA_FRAGMENT);
				Constructor<? extends YunaTubeBaseFragment> constructor = clazz.getConstructor((Class<?>[]) null);
				YunaTubeBaseFragment fragment = constructor.newInstance((Object[]) null);
				Bundle arg = new Bundle();
				arg.putAll(bundle);
				mContent = fragment.setBundle(arg);
			} catch(Exception e) {
				if (YunaTubeApplication.debuggable)
					mContent = new MainContentFragment();
			}
		}
		else
			mContent = new MainContentFragment();
		
		setContentView(R.layout.content_frame);
		getSupportFragmentManager()
		.beginTransaction()
		.replace(R.id.content_frame, mContent)
		.commit();
		setSlidingActionBarEnabled(false);

		// Configure the SlidingMenu
		menu.setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN);
		menu.setShadowWidthRes(R.dimen.shadow_width);
		menu.setShadowDrawable(R.drawable.shadow);
		menu.setBehindOffsetRes(R.dimen.slidingmenu_offset);
		menu.setFadeDegree(0.35f);
		menu.setMenu(R.layout.menu_frame);

		// Get screen width
		Display display = getWindowManager().getDefaultDisplay();
		Point size = new Point();
		int width, height;
		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
			display.getSize(size);
			width = size.x;
			height = size.y;
		} else {
			width = display.getWidth();
			height = display.getHeight();
		}
		menu.setBehindWidth(Math.min(width, height) * Utils.getInteger(R.integer.factor_1) / Utils.getInteger(R.integer.factor_2));

		mHandler = new Handler() {
			@Override
			public void handleMessage(Message msg) {
				if (msg.what == 0) {
					closeAppMsgFlag = false;
				}
			}
		};
		
		boolean localeChanged = Preference.getBoolean(IS_LOCALE_CHANGED);
		if (localeChanged && YunaTubeApplication.debuggable)
			Utils.showToast(this, "Locale changed");
			
		if (savedInstanceState == null || localeChanged) {
			startDownload();
		}
	}
	
	private void startDownload() {
		if (Utils.isNetworkAvailable() && Preference.get(YuNaTubeSqliteDatabase.IS_DB_AVAILABLE, true)) {
			Utils.debug("Starting XMLDownloadService");
			Intent intent = new Intent(this, DownloadService.class);
			startService(intent);
		}
	}
	
	@Override
	protected void onResume() {
		super.onResume();
		if (Preference.getBoolean(GCMIntentService.EXTRA_DO_UPDATE)) {
			Preference.remove(GCMIntentService.EXTRA_DO_UPDATE);
			if (YunaTubeApplication.debuggable)
				Utils.showToast(this, "Updaing due to Update flag");
			startDownload();
		}
		
		NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
		mNotificationManager.cancel(GCMIntentService.NOTIFICATION_ID);
	}
	
	@Override
	public void onSaveInstanceState(Bundle outState) {
		outState.putBoolean("service", true);
		super.onSaveInstanceState(outState);
	}

	@Override
	public void onBackPressed() {
		if (menu.isMenuShowing()) {
			menu.showContent();
		} else {
			if (mContent instanceof PhotoListFragment) {
				super.onBackPressed();
			} else {
				if (!closeAppMsgFlag) {
					Utils.showToast(this, R.string.main_back_message);
					closeAppMsgFlag = true;
					mHandler.sendEmptyMessageDelayed(0, 2000);
				} else {
					finish();
				}
			}
		}
	}

	@Override
	public boolean onPrepareOptionsMenu(Menu menu) {
		super.onPrepareOptionsMenu(menu);
		MenuItem item = menu.findItem(R.id.notification);
		if (item != null) {
			item.setChecked(notification);
		}
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		int itemId = item.getItemId();
		switch (itemId) {
		case android.R.id.home:
			if (menu.isMenuShowing())
				menu.showContent();
			else
				menu.showMenu();
			break;
			
		case R.id.search:
			setFragment(new SearchFragment(), false);
			break;
			
		case R.id.nickname:
			showNicknameDialog();
			break;
			
		case R.id.feedback:
			Utils.emailToMe(this, getString(R.string.feedback_subject), getString(R.string.feedback_text));
			break;
			
		case R.id.language:
			setLocale(Utils.isAppLocaleKorean() ? "en" : "ko");
			Preference.put(IS_LOCALE_CHANGED, true);
			break;
			
		case R.id.notification:
			notification = !notification;
			item.setChecked(notification);
			Preference.put(Constants.NOTIFICATION, notification);
			Utils.showToast(this, notification ? R.string.notification_set : R.string.notification_canceled);
			break;
			
		default:
			return super.onOptionsItemSelected(item);
		}
		return true;
	}

	public void setLocale(String lang) {
		Locale myLocale = new Locale(lang);
		Resources res = getResources();
		DisplayMetrics dm = res.getDisplayMetrics();
		Configuration conf = res.getConfiguration();
		conf.locale = myLocale;
		res.updateConfiguration(conf, dm);
		
		Intent refresh = new Intent(this, MainActivity.class);
		startActivity(refresh);
		overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
		finish();
	}
	
	public void setFragment(final YunaTubeBaseFragment fragment, boolean addToStack) {
		if (!isCurrentContent(fragment)) {
			FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
	
			if (fragment instanceof PhotoListFragment) {
				ft.setCustomAnimations(R.anim.fragment_slide_left_enter, R.anim.fragment_slide_left_exit, R.anim.fragment_slide_right_enter, R.anim.fragment_slide_right_exit);
			}
			ft.replace(R.id.content_frame, fragment);
			if (addToStack)
				ft.addToBackStack(fragment.getClass().getSimpleName());
			
			ft.commit();
			
			updateFragmentInfo(fragment);
		}

		menu.showContent();
	}
	
	public void updateFragmentInfo(final YunaTubeBaseFragment fragment) {
		mContent = fragment;
		int title = fragment.getTitle();
		if (title != 0)
			actionBarTitle.setText(title);
		else
			actionBarTitle.setText(fragment.getTextTitle());
	}

	public boolean isCurrentContent(final YunaTubeBaseFragment fragment) {
		int mContentTitle = mContent.getTitle();
		int fragmentTitle = fragment.getTitle();
		
		if ((mContentTitle == 0 && fragmentTitle != 0) || (mContentTitle != 0 && fragmentTitle == 0))
			return false;
		if (mContentTitle != 0 && fragmentTitle != 0)
			return (mContentTitle == fragmentTitle);
		return TextUtils.equals(mContent.getTextTitle(), fragment.getTextTitle());
	}
	
	private void showNicknameDialog() {
		final AlertDialog.Builder alert = new AlertDialog.Builder(this);
	    final EditText input = new EditText(this);
	    input.setFilters(new InputFilter[] { new InputFilter.LengthFilter(10) });
	    input.setLines(1);
    	input.setHint(R.string.nickname_length);
	    if (Preference.contains(NICKNAME))
	    	input.setText(Preference.getString(NICKNAME));
	    alert.setTitle(R.string.nickname_set);
	    alert.setMessage(R.string.nickname_desc);
	    alert.setView(input);
	    alert.setCancelable(false);
	    alert.setPositiveButton(R.string.dialog_save, new DialogInterface.OnClickListener() {
	        public void onClick(DialogInterface dialog, int whichButton) {
	            String value = input.getText().toString().trim();
	            if (TextUtils.isEmpty(value)) {
	            	Utils.showToast(MainActivity.this, R.string.enter_data);
	            }
	            else {
	            	Preference.put(NICKNAME, value);
	            	Utils.showToast(MainActivity.this, R.string.nickname_successful);
	            }
	        }
	    });
	    alert.show();
	}
	
	private void showRateDialog() {
		if (Preference.getInt(VISIT_NUMBER) > 2 && !Preference.get(IS_RATE_DONE, false)) {
			AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
			builder.setTitle(R.string.supermenu_rate).
			setMessage(R.string.rate_yunatube).
			setPositiveButton(R.string.supermenu_rate_now, new DialogInterface.OnClickListener() {
				public void onClick(DialogInterface dialog, int id) {
					String appPackageName = MainActivity.this.getPackageName();
					Intent marketIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + appPackageName));
					marketIntent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
					startActivity(marketIntent);

					Preference.put(IS_RATE_DONE, true);
					dialog.dismiss();
				}
			}).setNegativeButton(R.string.supermenu_rate_later, new DialogInterface.OnClickListener() {
				public void onClick(DialogInterface dialog, int id) {
					Preference.put(IS_RATE_DONE, false);
					dialog.dismiss();
				}
			});
			// Create the AlertDialog object and return it
			AlertDialog dialog = builder.create();
			dialog.show();
		}
	}
}